package com.chaihu.jpaDemo.modules.common.controller;

import com.chaihu.jpaDemo.common.constant.CommonConstant;
import com.chaihu.jpaDemo.common.exception.RestException;
import com.chaihu.jpaDemo.common.searchBean.SearchCondition;
import com.chaihu.jpaDemo.utils.SpringUtil;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;

import javax.servlet.http.HttpServletRequest;
import javax.validation.ConstraintViolation;
import javax.validation.Validator;
import java.util.*;
import java.util.stream.Collectors;


/**
 *
 * Create By qinzhw
 * 2018年4月12日下午3:37:26
 */
public class BaseController {
    public Logger logger = LoggerFactory.getLogger(this.getClass());


    @Autowired
    public HttpServletRequest request;


    @Autowired
    Validator globalValidator;

    public String getUserToken() {
        String token = request.getHeader("token");
        if(StringUtils.isBlank(token)){
            token = request.getParameter("token");
        }
        if(StringUtils.isBlank(token)){
            token = request.getSession().getId();
        }
        return token;
    }

    /**
     * 描述: hibernate validator 获取验证后的错误信息 作者: qinzhw
     */
    public String getValidErrorMsg(BindingResult... brs) {
        List<String> msglist = new ArrayList<>();
        for (BindingResult br: brs) {
            List<ObjectError> errors = br.getAllErrors();
            errors.forEach(error -> msglist.add(error.getDefaultMessage()));
        }
        return StringUtils.join(msglist, "|");
    }

    /**
     * 封装分页信息
     *
     * @author shixh
     * @param pageNumber
     * @param pagzSize
     * @param sort
     * @return
     */
    public PageRequest buildPageRequest(int pageNumber, int pagzSize, Sort sort) {
        return new PageRequest(pageNumber - 1, pagzSize, sort);
    }

    /**
     * 封装分页信息
     *
     * @author shixh
     * @param pageNumber
     * @param pagzSize
     * @return
     */
    public PageRequest buildPageRequest(int pageNumber, int pagzSize) {
        return new PageRequest(pageNumber - 1, pagzSize);
    }


    /**
     * 封装分页信息
     * @param pageNumber
     * @param pagzSize
     * @param sort
     * @param sortType
     * @return
     */
    public PageRequest buildPageRequest(int pageNumber, int pagzSize, String[] sort, String[] sortType) {
        Sort s;
        if (sort != null && sort.length != 0) {
            int length = sort.length;
            List<Sort.Order> orders = new ArrayList<Sort.Order>(length);
            if(sortType == null || sortType.length == 0 || sortType.length != length) {
                sortType = new String[length];
                for (int i = 0; i < length; i++) {
                    sortType[i] = "ASC";
                }
            }
            for (int i = 0; i < length; i++) {
                if (StringUtils.isBlank(sort[i])) {
                    continue;
                }
                Sort.Order order = new Sort.Order(Sort.Direction.fromString(sortType[i]), sort[i]);
                orders.add(order);
            }
            s = new Sort(orders);
        } else {
            s = new Sort(new Sort.Order(Sort.Direction.ASC,"id"));
        }

        return new PageRequest(pageNumber - 1, pagzSize, s);
    }

    /**
     * 封装分页信息,支持多条件排序
     * 	"sort":["type","id"],
     *  "sortType":["DESC","ASC"],
     */
    public PageRequest buildPageRequest(Map<String, Object> searchParams) {
        String pageNum = (String) searchParams.get(CommonConstant.PAGE_PAGENUM);
        String pageSize = (String) searchParams.get(CommonConstant.PAGE_PAGESIZE);
        Object o = searchParams.get(CommonConstant.PAGE_SORTTYPE);
        Object o1 = searchParams.get(CommonConstant.PAGE_SORT);
        String[] sortType = null;
        String[] sort = null;

        if (o instanceof ArrayList) {
            ArrayList arrayList = (ArrayList) searchParams.get(CommonConstant.PAGE_SORTTYPE);
            sortType = new String[arrayList.size()];
            for (int i = 0; i <arrayList.size() ; i++) {
                sortType[i] = arrayList.get(i).toString();
            }
        }else if(o instanceof String ) {
            sortType = new String[] {(String) searchParams.get(CommonConstant.PAGE_SORTTYPE)};
        }
        if (o1 instanceof ArrayList) {
            ArrayList arrayList = (ArrayList) searchParams.get(CommonConstant.PAGE_SORT);
            sort = new String[arrayList.size()];
            for (int i = 0; i <arrayList.size() ; i++) {
                sort[i] = arrayList.get(i).toString();
            }
        }else if(o1 instanceof String ) {
            sort = new String[] {(String) searchParams.get(CommonConstant.PAGE_SORT)};
        }

        if (StringUtils.isBlank(pageNum)) {
            pageNum = CommonConstant.PAGE_1;
        }
        if (StringUtils.isBlank(pageSize)) {
            pageSize = CommonConstant.PAGE_10;
        }
        searchParams.remove(CommonConstant.PAGE_PAGENUM);
        searchParams.remove(CommonConstant.PAGE_PAGESIZE);
        searchParams.remove(CommonConstant.PAGE_SORTTYPE);
        searchParams.remove(CommonConstant.PAGE_SORT);
        return buildPageRequest(Integer.parseInt(pageNum), Integer.parseInt(pageSize), sort, sortType);
    }

    /**
     * 请求参数转MAP
     *
     * @author shixh
     * @return
     */
    public Map<String, Object> getParameterMap() {
        Map<String,String[]> properties = request.getParameterMap();
        Map<String, Object> returnMap = new HashMap<>();
        Iterator<Map.Entry<String,String[]>> entries = properties.entrySet().iterator();
        Map.Entry<String,String[]> entry;
        String name = "";
        Object value = "";
        while (entries.hasNext()) {
            entry = entries.next();
            name = entry.getKey();
            Object valueObj = entry.getValue();
            if (null == valueObj) {
                value = "";
                continue; /*值为空时 忽略查询字段 add by chaihu*/
            } else if (valueObj instanceof String[]) {
                String valueStr = "";
                String[] values = (String[]) valueObj;
                for (int i = 0; i < values.length; i++) {
                    valueStr = values[i] + ",";
                }
                value = valueStr.substring(0, valueStr.length() - 1);
            } else {
                value = valueObj;
            }
            returnMap.put(name, value);
        }
        return returnMap;
    }

    public Map<String, Object> excludeNull(Map<String, Object> paramMap) {
        Set<String> set = paramMap.keySet();
        Iterator<String> it = set.iterator();
        List<String> listKey = new ArrayList<String>();
        while (it.hasNext()) {
            String str = it.next();
            if(paramMap.get(str)==null || "".equals(paramMap.get(str))){
                listKey.add(str) ;
            }
        }
        for (String key : listKey) {
            paramMap.remove(key);
        }
        return paramMap;
    }

    public PageRequest buildPageRequest(SearchCondition condition) {
        if (condition.getPageNumber() < 1){
            condition.setPageNumber(CommonConstant.PAGE_PAGENUM_DEFAULT);
        }
        if (condition.getPageSize() < 1) {
            condition.setPageSize(CommonConstant.PAGE_PAGESIZE_DEFAULT);
        }
        List<Sort.Order> orders=new ArrayList<>();
        List<com.chaihu.jpaDemo.common.searchBean.Sort> sortList = condition.getSortList();
        if(null != sortList &&!sortList.isEmpty()) {
            for (com.chaihu.jpaDemo.common.searchBean.Sort sort  : sortList) {
                orders.add(new Sort.Order(Sort.Direction.fromString(sort.getStyle().name()), sort.getField()));
            }
        }else {
            orders.add( new Sort.Order(Sort.Direction.ASC, "id"));
        }
        return new PageRequest(condition.getPageNumber() - 1, condition.getPageSize(), new Sort(orders));
    }



    /**
     * 描述: Controller层检查dto中的属性是否符合规定,错误信息Validator筛出，抛出异常返回
     * 作者: qinzhw
     */
    public void checkDto(Object dto) throws RestException {
        String dtoErrMsg = getDtoErrMsg(dto);
        if (StringUtils.isNotBlank(dtoErrMsg)) {
            throw new RestException(dtoErrMsg);
        }
    }
    public String getDtoErrMsg(Object dto) {
        Validator validator = SpringUtil.getBean(Validator.class);
        Set<ConstraintViolation<Object>> violationSet = validator.validate(dto);
        if (!CollectionUtils.isEmpty(violationSet)) {
            List<String> errorStrs = violationSet.stream().map(violation -> {
                return violation.getMessage();
            }).collect(Collectors.toList());
            return StringUtils.join(errorStrs, "|");
        }
        return "";
    }
}
